package de.idgard.android.addon.ui.services.impl;

import java.util.List;

import android.webkit.CookieManager;
import android.webkit.WebView;
import de.idgard.android.addon.backend.IDGBackendService;
import de.idgard.android.addon.proxy.services.ProxyService;
import de.idgard.android.addon.services.GlobalServiceRegistry;
import de.idgard.android.addon.ui.services.AddonStateService;
import de.idgard.android.addon.ui.services.BrowserPrivateModeService;
import de.idgard.android.addon.ui.services.BrowserTabService;
import de.idgard.android.addon.ui.services.BrowserUtilityService;
import de.idgard.android.addon.ui.services.JavaScriptLoaderService;
import de.idgard.android.addon.ui.services.OrchestrationService;
import de.idgard.android.addon.ui.services.TransparencyStateService;
import de.idgard.android.addon.ui.services.TransparencyStateService.TransparencyState;
import de.idgard.android.addon.ui.services.ZircoToIDGardAPI;
import de.idgard.android.addon.ui.services.dto.ExtendedState;
import de.idgard.android.addon.ui.services.dto.MessageDTO;
import de.idgard.webapp.shared.dto.privacy.HistoryItemDto;

public class OrchestrationServiceImpl implements OrchestrationService {

	private ZircoToIDGardAPI api;

	public void setApi(ZircoToIDGardAPI api) {
		this.api = api;
	}

	private TransparencyStateService transparencyStateService;

	public TransparencyStateService getTransparencyStateService() {
		return transparencyStateService;
	}

	public void setTransparencyStateService(TransparencyStateService transparencyStateService) {
		this.transparencyStateService = transparencyStateService;
	}

	private BrowserPrivateModeService browserPrivateModeService;
	private BrowserTabService browserTabService;
	private BrowserUtilityService browserUtilityService;
	private AddonStateService addonStateService;

	public void setBrowserPrivateModeService(BrowserPrivateModeService browserPrivateModeService) {
		this.browserPrivateModeService = browserPrivateModeService;
	}

	public void setBrowserTabService(BrowserTabService browserTabService) {
		this.browserTabService = browserTabService;
	}

	public void setBrowserUtilityService(BrowserUtilityService browserUtilityService) {
		this.browserUtilityService = browserUtilityService;
	}

	public void setAddonStateService(AddonStateService addonStateService) {
		this.addonStateService = addonStateService;
	}

	private IDGBackendService getIDGBackendService() {
		return GlobalServiceRegistry.instance().getBackendService();
	}

	private ProxyService getProxyService() {
		return GlobalServiceRegistry.instance().getProxyService();
	}

	private JavaScriptLoaderService getJavaScriptLoader() {
		return GlobalServiceRegistry.instance().getJavaScriptLoaderService();
	}

	private BrowserPrivateModeService getBrowserPrivateModeService() {
		return browserPrivateModeService;
	}

	private BrowserTabService getBrowserTabService() {
		return browserTabService;
	}

	private AddonStateService getAddonStateService() {
		return addonStateService;
	}

	private BrowserUtilityService getBrowserUtilityService() {
		return browserUtilityService;
	}

	@Override
	public void handleAddonClosinFromExistingState() {
		try {
			getBrowserTabService().closeAllTabsInOnModeBrowserState();
			getAddonStateService().configureAddonState(ExtendedState.ON_LOGIN);
			getTransparencyStateService().configureTransparencyState(TransparencyState.NORMAL);
			getProxyService().stopServiceAndLocalProxy();
			getIDGBackendService().logoff().fire();
			getBrowserUtilityService().invalidateIDGardONModeCookies();
			api.clearDownloads();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void handleSessionExpiration() {
		try {
			getAddonStateService().configureAddonState(ExtendedState.ON_LOGIN);
			getProxyService().stopServiceAndLocalProxy();
			getBrowserUtilityService().invalidateIDGardONModeCookies();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean checkUrlAndReact(String url) {
		if (!getBrowserUtilityService().checkIfIDGardLoginUrl(url)) {
			return false;
		}
		try {
			getAddonStateService().configureAddonState(ExtendedState.ON_LOGIN);
			getProxyService().stopServiceAndLocalProxy();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return true;
	}

	@Override
	public void configureWebView(WebView view) {
		if (!getAddonStateService().isAddonON()) {
			return;
		}
		getBrowserPrivateModeService().configureBrowserPrivateMode(view);
		getBrowserUtilityService().provisionUserAgentString(view);
	}

	private boolean canLoadJS(String url) {
		return !getBrowserUtilityService().checkIfIDStartPage(url) && !getBrowserUtilityService().checkIfIDGardDomainOrigination(url)
				&& getAddonStateService().isAddonON() && !getTransparencyStateService().isTransparent();
	}

	private boolean canSubmitHistory(String url) {
		return getAddonStateService().isAddonON() && !getBrowserUtilityService().checkIfIDStartPage(url)
				&& !getBrowserUtilityService().checkIfIDGardDomainOrigination(url);
	}

	@Override
	public MessageDTO handleLoadedUrl(String url, WebView view) {
		if (canSubmitHistory(url)) {
			getIDGBackendService().submitHistoryEntry(new HistoryItemDto(url, view.getTitle())).fire();
		}
		MessageDTO dto = new MessageDTO();
		if (getBrowserUtilityService().checkIfIDGardDomainOrigination(url)) {
			view.loadUrl(getJavaScriptLoader().getOneClickLoginListenerScript());
		}
		if (canLoadJS(url)) {
			view.loadUrl(getJavaScriptLoader().getPrivacyConnectScript());
		}
		// HANDLE SESSION TIMEOUT
		if (getBrowserUtilityService().checkIfIDGardLoginUrl(url)) {
			if (getAddonStateService().isAddonON()) {
				handleSessionExpiration();
				dto.addAction("updateIDGardGui");
				if (!getBrowserUtilityService().checkIfOpenLoginPageWithWebApp()) {
					dto.addAction("openLoginPage");
				}
				return dto;
			} else {
				// add on is not on
				if (!getBrowserUtilityService().checkIfOpenLoginPageWithWebApp()) {
					dto.addAction("openLoginPage");
					return dto;
				}
			}
		}

		if (!getBrowserUtilityService().checkIfIDGardDomainOrigination(url) && (getAddonStateService().isAddonOFF())) {
			return dto;
		}
		String cookie = CookieManager.getInstance().getCookie(url);
		if (!(cookie == null && !getBrowserUtilityService().checkIfIDGardLoginUrl(url)) && !getBrowserUtilityService().isCookieValid(cookie)) {
			return dto;
		}
		/**************/
		if (cookie != null && !getAddonStateService().isAddonON()) {
			getBrowserUtilityService().extractIDGardCookieData(url);

			if (!getProxyService().isLocalProxyON()) {
				getProxyService().startProxyService();
			}
			getAddonStateService().configureAddonState(ExtendedState.ON);
			configureWebView(view);
			dto.addAction("loginCompleted");
			dto.addAction("updateIDGardGui");
		}
		return dto;
	}

	@Override
	public void handleApplicationExit() {
		getAddonStateService().configureAddonState(ExtendedState.OFF);
		getBrowserUtilityService().invalidateIDGardONModeCookies();
		getProxyService().stopServiceAndLocalProxy();
	}

	public void adjustForTransparencyLevel(TransparencyState level) {
		getTransparencyStateService().configureTransparencyState(level);
		getProxyService().adjustProxySettingsBasedOnTransparency(level);
		getBrowserPrivateModeService().configureBrowserPrivateModeForAllViews();
		getBrowserTabService().reloadAllTabs();
	}

	@Override
	public MessageDTO restoreAddonState() {
		MessageDTO dto = new MessageDTO();
		if (getAddonStateService().isAddonON()) {
			dto.addAction("updateIDGardGui");
		} else if (getAddonStateService().isAddonONLOGIN()) {
			dto.addAction("updateIDGardGui");
		} else if (getAddonStateService().isAddonOFF() || getAddonStateService().isAddonONLOGIN()) {
			getAddonStateService().configureAddonState(ExtendedState.ON_LOGIN);
			dto.addAction("updateIDGardGui");
		}
		return dto;
	}

	@Override
	public void handleExistingViewsUponLogin() {
		List<WebView> views = getBrowserPrivateModeService().configureBrowserPrivateModeForAllViews();
		for (WebView view : views) {
			browserUtilityService.provisionUserAgentString(view);
			if (browserUtilityService.checkIfIDGardLoginUrl(view.getUrl())) {
				view.goBack();
			}
		}
	}

}
